<?php



/**
 * Skeleton subclass for representing a row from the 'reservation' table.
 *
 * 
 *
 * You should add additional methods to this class to meet the
 * application requirements.  This class will only be generated as
 * long as it does not already exist in the output directory.
 *
 * @package    propel.generator.ise-php
 */
class Reservation extends BaseReservation {

	// attempts to reload the foreign key references
	public function reloadReferences() {
		if (isset($this->customerid)) {
			$this->setCustomer(CustomerQuery::create()->findPk($this->customerid));
		}
		if (isset($this->pickup)) {
			$this->setStationRelatedByPickup(StationQuery::create()->findPk($this->pickup));
		}
		if (isset($this->dropoff)) {
			$this->setStationRelatedByDropoff(StationQuery::create()->findPk($this->dropoff));
		}
		if (isset($this->catname)) {
			$this->setCategory(CategoryQuery::create()->findPk($this->catname));
		}
		return $this;
	}
	
	// runs all business logic validation tests
	public function isValid() {
		return $this->checkFKs() && $this->checkAge() && $this->checkStationCategories() && 
			$this->checkTimes();
	}
	
	// validity functions
	
	// all required entities set?
	public function checkFKs() {
		if (!isset($this->aCustomer)) {
			throw new DomainException("missing customer");
		}
		if (!isset($this->aStationRelatedByDropoff)) {
			throw new DomainException("missing dropoff station");
		}
		if (!isset($this->aStationRelatedByPickup)) {
			throw new DomainException("missing pickup station");
		}
		if (!isset($this->aCategory)) {
			throw new DomainException("missing category");
		}
		return true;
	}
	
	// customer has min age for chosen category?
	public function checkAge() {
		if (!isset($this->aCategory)) {
			throw new DomainException("missing category");
		}
		if (!isset($this->aCustomer)) {
			throw new DomainException("missing customer");
		}
		if ($this->aCategory->getMinage() <= $this->aCustomer->getPerson()->getAge()) {
			return true;
		}
		throw new InvalidArgumentException(
					"Customer's [".$this->aCustomer->getWebuser()->getUsername()."] age does not meet required age of category [".$this->aCategory->getMinage()."]");
	}
	
	// start date before end date?
	public function checkTimes() {
		if (!isset($this->ends)) {
			throw new DomainException("missing end date");
		}
		if (!isset($this->starts)) {
			throw new DomainException("missing start date");
		}
		if ($this->getEnds(null) > $this->getStarts(null)) {
			return true;
		}
		throw new InvalidArgumentException("start date [".$this->starts."] must be before end date [".$this->ends."]");
	}
	
	// chosen stations accept chosen category?
	public function checkStationCategories() {
		if (!isset($this->aCategory)) {
			throw new DomainException("missing category");
		}
		if (!isset($this->aStationRelatedByDropoff)) {
			throw new DomainException("missing dropoff station");
		}
		if (!isset($this->aStationRelatedByPickup)) {
			throw new DomainException("missing pickup station");
		}
		$catname = $this->aCategory->getCatname();
		if ($this->aStationRelatedByDropoff->getOfferss(OffersQuery::create()->filterByCategory($this->aCategory)) &&
				$this->aStationRelatedByPickup->getOfferss(OffersQuery::create()->filterByCategory($this->aCategory))
				) {
			return true;	
		} else {
			throw new InvalidArgumentException("pickup [".$this->aStationRelatedByPickup->getStationname()."] and dropoff [".$this->aStationRelatedByDropoff->getStationname()."] stations must support category [".$this->aCategory->getCatname()."]");
		}
	}
	
	// calculate price
	public function calculatePrice() {
		if (isset($this->aCategory) && isset($this->aCustomer) && $this->checkTimes()) {
			// calc days
			$days = $this->getEnds(null)->diff($this->getStarts(null),true)->d;
			// category base price
			$basePrice = $this->aCategory->getPrice();
			// 10% off if premium customer
			$discount = $this->aCustomer->getPremium() ? 0.9 : 1;
			// set price
			$this->setPrice($days * $basePrice * $discount);
			return $this;
		}
		throw new DomainException("missing parameters for price calculation");
	}
	
	// sets creation time as now
	public function place() {
		$this->setPlaced(new DateTime());
		return $this;
	}
	
} // Reservation
